// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

import { _decorator, Component, Node, Canvas, Size, Vec3, view, game, Camera, toRadian, SystemEventType } from 'cc';
import { EDITOR } from 'cc/env';
const { ccclass, property } = _decorator;

const _worldPos = new Vec3();

@ccclass('Canvas3d')
export class Canvas3d extends Canvas {

    private _pos = new Vec3();

    @property(Camera)
    camera3d: Camera = null!;

    constructor () {
        super();

        if (EDITOR) {
            this._fitDesignResolution = () => {
                // TODO: support paddings of locked widget
                let nodeSize: Size; let designSize: Size;
                this.node.getPosition(this._pos);
                nodeSize = designSize = view.getDesignResolutionSize();
                Vec3.set(_worldPos, 0, 0, 0);

                if (!this._pos.equals(_worldPos)) {
                    this.node.setPosition(_worldPos);
                }
                const trans = this.node._uiProps.uiTransformComp!;
                if (trans.width !== nodeSize.width) {
                    trans.width = nodeSize.width;
                }
                if (trans.height !== nodeSize.height) {
                    trans.height = nodeSize.height;
                }
            };
        }
    }

    
    public __preload () {

        super.__preload();

        if (!EDITOR) {
            const camera = this._camera!;            
            camera.projectionType = this.camera3d.projection;
            camera.fovAxis = this.camera3d.fovAxis;
            camera.fov = toRadian(this.camera3d.fov);
            camera.orthoHeight = this.camera3d.orthoHeight;
            camera.nearClip = this.camera3d.near;
            camera.farClip = this.camera3d.far;        
        }

        this.camera3d.node.on(SystemEventType.TRANSFORM_CHANGED, this._thisOnCameraResized);
    }

    public onDestroy () {
        super.onDestroy();
        this.camera3d.node.off(SystemEventType.TRANSFORM_CHANGED, this._thisOnCameraResized);
    }


    protected _onResizeCamera () {
        const camera = this._camera;
        if (camera) {
            if (this._targetTexture) {
                const win = this._targetTexture.window;
                camera.setFixedSize(win!.width, win!.height);
                camera.orthoHeight = view.getVisibleSize().height / 2;
            } else {
                const size = game.canvas!;
                camera.resize(size.width, size.height);
                camera.orthoHeight = game.canvas!.height / view.getScaleY() / 2;
            }
            camera.node.setPosition((this.camera3d.node.getWorldPosition()));
            camera.node.eulerAngles = this.camera3d.node.eulerAngles;
            camera.node.scale = this.camera3d.node.scale;
            camera.update();
        }
    }

}
